import { isObject } from "feok-lib";

function _transformRequest(data: any) {
  let ret = "";
  Object.keys(data).forEach((key) => {
    ret += _transform(key, data[key]);
  });
  ret = ret.replace(/&$/, ""); // 替换最后一个 &
  return ret;
}


function _transform(key: string, data: any) {
  if (Array.isArray(data)) { // 数组
    if (isComplexArray(data)) { // 如果是复杂数组
      return encodeKeyValue(key, JSON.stringify(data)) + "&";
    } else {
      return expantsToString(key, data);
    }
  }
  if (typeof data === "object") {
    return encodeKeyValue(key, JSON.stringify(data)) + "&";
  }
  return encodeKeyValue(key, data) + "&";
}
/**
 * 是否为复杂数组
 * [{},{}] -> return true
 * [1,2,3] -> return false
 * @param data 数组
 */
function isComplexArray(data: any[]) {
  if (data.length) {
    return typeof data[0] === "object";
  }
  return false;
}

function expantsToString(key: string, data: any[]) {
  let ret = "";
  data.forEach((item) => {
    ret += encodeKeyValue(`${key}[]`, item) + "&";
  });
  return ret;
}

function encodeKeyValue(key: string, value: any) {
  return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
}

class ContentType {
  // constructor (options) {}
  public apply(orm: any) {
    orm._post = orm.post;
    orm.post = (config: any, ...middlewares: any[]) => (params: any, query: any) => {
      const configObject = isObject(config)
        ? config
        : {
          url: config
        };
      return orm._post({
        transformRequest: [
          _transformRequest
        ],
        ...configObject
      }, ...middlewares).call(orm, params, query);
    };
    orm._put = orm.put;
    orm.put = (config: any, ...middlewares: any[]) => (params: any, query: any) => {
      const configObject = isObject(config)
        ? config
        : {
          url: config
        };
      return orm._put({
        transformRequest: [_transformRequest],
        ...configObject
      }, ...middlewares).call(orm, params, query);
    };
    orm._get = orm.get;
    orm.get = (config: any, ...middlewares: any[]) => (params: any, query: any) => {
      params && Object.keys(params).forEach((key) => {
        if (params[key] === "" || params[key] === null || params[key] === undefined) {
          delete params[key];
        }
      });
      const configObject = isObject(config)
        ? config
        : {
          url: config
        };
      return orm._get({
        transformRequest: [(data: any) => {
          return data;
        }],
        ...configObject
      }, ...middlewares).call(orm, params, query);
    };
  }
}

export default ContentType;
